package pl.edu.agh.neuraleconomy.core.experiment.filter;

import java.util.LinkedList;
import java.util.List;

import org.apache.commons.math3.stat.descriptive.moment.Mean;
import org.apache.commons.math3.stat.descriptive.moment.StandardDeviation;
import org.apache.log4j.Logger;

import pl.edu.agh.neuraleconomy.core.nn.CoreUtils;
import pl.edu.agh.neuraleconomy.model.exchange.Company;
import pl.edu.agh.neuraleconomy.model.exchange.Exchange;
import pl.edu.agh.neuraleconomy.persistence.base.DaoProvider;
import pl.edu.agh.neuraleconomy.persistence.exchange.ExchangeDao;

public class StandardDeviationFilter implements ICompanyFilter{
	private Logger logger = Logger.getLogger(getClass());
	protected double minDeviation = 0.0;
	protected double maxDeviation = 1.0;
	private ExchangeDao dao = DaoProvider.getExchangeDao();
	
	public StandardDeviationFilter() {
	}
	
	public StandardDeviationFilter(double minDeviation, double maxDeviation) {
		this.minDeviation = minDeviation;
		this.maxDeviation = maxDeviation;
	}
	
	public List<Company> filter(List<Company> companies) {
		List<Company> result = new LinkedList<Company>();
		
		for(Company c : companies){
			if(verifyCompany(c)){
				result.add(c);
				logger.info(String.format("Adding company: %s", c.toString()));
			}
		}
		
		return result;
	}
	
	private boolean verifyCompany(Company c){
		List<Exchange> exhchanges = dao.getByCompany(c.getId());
		
		double closingPrices [] = CoreUtils.toDoubleArray(exhchanges);
		
		double mean = (new Mean()).evaluate(closingPrices);
		double deviation = (new StandardDeviation()).evaluate(closingPrices, mean);
		
		logger.debug(String.format("Deviation: %s, Mean: %s", String.valueOf(deviation), String.valueOf(mean)));
			
		return include(mean, deviation);
	}

	protected boolean include(double mean, double deviation) {
		double devDivMean = deviation / mean;
		return devDivMean > minDeviation && devDivMean < maxDeviation;
	}

}
